/**
 * @ DateUtils.java
 * 版权声明  版权所有(中国通信服务福建邮科) 违者必究
 * 版本号  1.0
 * 修订记录:
 * 1)更改者：林伟
 * 时　间：2012-7-26 上午10:47:36
 * 描　述：创建
 */
package com.devframe.sys.util.common;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import com.devframe.sys.util.assertion.Assert;


/**
 * <pre>
 * 时间工具类
 * </pre>
 *
 * JDK版本:1.4 或更高
 * @author 林伟
 * @version 1.0
 * @since 1.0
 */
@SuppressWarnings("all")
public class DateUtils {
	
	/** 一分钟的秒数 */
	public static final int SECONDS_ONE_MINUTE = 60;
	
	/** 一秒的毫秒数 */
	public static final int MILLISECONDS_ONE_SECOND = 1000;
	
	/** 一小时的秒数 */
	public static final int SECONDS_ONE_HOUR = 60 * SECONDS_ONE_MINUTE;
	
	/** 一天的秒数 */
	public static final int SECONDS_ONE_DAY = 24 * SECONDS_ONE_HOUR;
	
    /** 数据库存储的时间格式串，如yyyymmdd 或yyyymmddHHMiSS */
    public static final int DB_STORE_DATE = 1;

    /** 用连字符-分隔的时间时间格式串，如yyyy-mm-dd 或yyyy-mm-dd HH:Mi:SS */
    public static final int HYPHEN_DISPLAY_DATE = 2;

    /** 用连字符.分隔的时间时间格式串，如yyyy.mm.dd 或yyyy.mm.dd HH:Mi:SS */
    public static final int DOT_DISPLAY_DATE = 3;

    /** 用中文字符分隔的时间格式串，如yyyy年mm月dd 或yyyy年mm月dd HH:Mi:SS */
    public static final int CN_DISPLAY_DATE = 4;
    /** 日期的开始时间戳*/
    
    public static final String DB_STORE_DATE_BEGIN = "000000";
    
    /** 日期的结束时间戳*/
    public static final String DB_STORE_DATE_END = "235959";
    
	/**
	 * 获取当前Date类型的时间
	 * 
	 * @param formatStr
	 * @return
	 */
	public static Date getCurrDate(String formatStr) {
		SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
		String dateStr = sdf.format(new Date());
		Date date = new Date();
        try {
        	date= sdf.parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}
	
	public static Date getCurrentDate(){
		String formatStr = "yyyy-MM-dd HH:mm:SS";
		return DateUtils.getCurrDate(formatStr);
	}
	
	/**
	 * 获取当前String类型的时间
	 * 
	 * @param formatStr
	 * @return
	 */
	public static String getCurrTime(String formatStr) {
		SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
		return sdf.format(new Date());
	}
	
	/**
     * 获取当前月份的第一天
     * @return 第一天的日期对象
     * @author:  
     */
    public static Date getCurMonthFirstDate(){
    	Calendar calendar = Calendar.getInstance();
    	calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
    	return calendar.getTime();
    }
    
    /**
     * 获取当前月份的最后一天
     * @return 最后一天的日期对象
     * @author:  
     */
    public static Date getCurMonthLastDay() {      
    	Calendar calendar = Calendar.getInstance();      
    	calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));      
    	return calendar.getTime();
    }   
     
    /**
     * 获取日期的开始时间戳
     * @param storeDate 数据库存储日期，格式yyyyMMddHHmmss
     * @return storeDate
     * @author:  
     */
    public static String getStoreDateBegin(String storeDate){
    	if(storeDate.length() >= 8){
    		return storeDate.substring(0,8)+DB_STORE_DATE_BEGIN;
    	}else{
    		return storeDate;
    	}
    }
    
    /**
     * 获取日期的结束时间戳
     * @param storeDate 数据库存储日期，格式yyyyMMddHHmmss
     * @return storeDate
     * @author:  
     */
    public static String getStoreDateEnd(String storeDate){
    	if(storeDate.length() >= 8){
    		return storeDate.substring(0,8)+DB_STORE_DATE_END;
    	}else{
    		return storeDate;
    	}
    }

    /**
     * 得到精确到秒的格式化当前时间串
     * 
     * @param formatType
     *            时间格式的类型{@link #DB_STORE_DATE},{@link #EN_HTML_DISPLAY_DATE},{@link #CN_HTML_DISPLAY_DATE}
     * @return 当前时间格式化时间串
     */
    public static String getCurrTimeStr(int formatType) {
        return getTimeStr(new Date(), formatType);
    }

    /**
     * 得到精确到秒的格式化时间串
     * 
     * @param date
     *            指定时间
     * @param formatType
     *            时间格式的类型{@link #DB_STORE_DATE},{@link #EN_HTML_DISPLAY_DATE},{@link #CN_HTML_DISPLAY_DATE}
     * @return 指定时间的格式化时间串
     */
    public static String getTimeStr(Date date, int formatType) {
        if (formatType < DB_STORE_DATE || formatType > CN_DISPLAY_DATE) {
            throw new IllegalArgumentException("时间格式化类型不是合法的值。");
        } else {
            String formatStr = null;
            switch (formatType) {
            case DB_STORE_DATE:
                formatStr = "yyyyMMddHHmmss";
                break;
            case HYPHEN_DISPLAY_DATE:
                formatStr = "yyyy'-'MM'-'dd HH:mm:ss";
                break;
            case DOT_DISPLAY_DATE:
                formatStr = "yyyy.MM.dd HH:mm:ss";
                break;
            case CN_DISPLAY_DATE:
                formatStr = "yyyy'年'MM'月'dd HH:mm:ss";
                break;
            default:
                formatStr = "yyyyMMddHHmmss";
                break;
            }
            SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
            return sdf.format(date);
        }
    }

    /**
     * 得到精确到天的当前格式化日期串
     * 
     * @param formatType
     *            时间格式的类型{@link #DB_STORE_DATE},{@link #EN_HTML_DISPLAY_DATE},{@link #CN_HTML_DISPLAY_DATE}
     * @return String
     */
    public static String getCurrDateStr(int formatType) {
        return getDateStr(new Date(), formatType);
    }

    /**
     * 得到精确到天的指定时间格式化日期串
     * 
     * @param date
     *            指定时间
     * @param formatType
     *            时间格式的类型{@link #DB_STORE_DATE},{@link #EN_HTML_DISPLAY_DATE},{@link #CN_HTML_DISPLAY_DATE}
     * @return 指定时间格式化日期串
     */
    public static String getDateStr(Date date, int formatType) {
        if (formatType < DB_STORE_DATE || formatType > CN_DISPLAY_DATE) {
            throw new IllegalArgumentException("时间格式化类型不是合法的值。");
        } else {
            String formatStr = null;
            switch (formatType) {
            case DB_STORE_DATE:
                formatStr = "yyyyMMdd";
                break;
            case HYPHEN_DISPLAY_DATE:
                formatStr = "yyyy-MM-dd";
                break;
            case DOT_DISPLAY_DATE:
                formatStr = "yyyy.MM.dd";
                break;
            case CN_DISPLAY_DATE:
                formatStr = "yyyy'年'MM'月'dd";
                break;
            default:
                formatStr = "yyyyMMdd";
                break;
            }
            SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
            return sdf.format(date);
        }
    }

    /**
     * 得到精确到月的当前时间格式化年月串
     * 
     * @param formatType
     *            时间格式的类型{@link #DB_STORE_DATE},{@link #EN_HTML_DISPLAY_DATE},{@link #CN_HTML_DISPLAY_DATE}
     * @return 精确到月当前时间格式化年月串
     */
    public static String getYearMonthStr(int formatType) {
        return getYearMonthStr(new Date(), formatType);
    }

    /**
     * 得到精确到月的指定时间格式化年月串
     * 
     * @param date
     *            指定的时间
     * @param formatType
     *            时间格式的类型{@link #DB_STORE_DATE},{@link #EN_HTML_DISPLAY_DATE},{@link #CN_HTML_DISPLAY_DATE}
     * @return 精确到月当前时间格式化年月串
     */
    public static String getYearMonthStr(Date date, int formatType) {
        if (formatType < DB_STORE_DATE || formatType > CN_DISPLAY_DATE) {
            throw new IllegalArgumentException("时间格式化类型不是合法的值。");
        } else {
            String formatStr = null;
            switch (formatType) {
            case DB_STORE_DATE:
                formatStr = "yyyyMM";
                break;
            case HYPHEN_DISPLAY_DATE:
                formatStr = "yyyy-MM";
                break;
            case DOT_DISPLAY_DATE:
                formatStr = "yyyy.MM";
                break;
            case CN_DISPLAY_DATE:
                formatStr = "yyyy'年'MM'月'";
                break;
            default:
                formatStr = "yyyyMM";
                break;
            }

            SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
            return sdf.format(date);
        }
    }
    
	/**
	 * 将null字符串转换为空串，方便HTML的显示
	 * 
	 * @param sourceStr
	 *            待处理的字符串
	 * @return String 处理的的字符串
	 */
	public static String toVisualString(String sourceStr) {
		if (sourceStr == null || sourceStr.equals("")) {
			return "";
		} else {
			return sourceStr;
		}
	}
	
    /**
     * 将数据库存储的日期格式串转换为各种显示的格式
     * 
     * @param dateStr
     *            最小6位，最大14位的数据库存储格式时间串如:20041212
     * @param formatType
     *            时间格式的类型{@link #DB_STORE_DATE},{@link #EN_HTML_DISPLAY_DATE},{@link #CN_HTML_DISPLAY_DATE}
     * @return 格式化的时间串
     */
    public static String toDisplayStr(String dateStr, int formatType) {
        if (formatType < DB_STORE_DATE || formatType > CN_DISPLAY_DATE) {
            throw new IllegalArgumentException("时间格式化类型不是合法的值。");
        }
        if (dateStr == null || dateStr.length() < 6 || dateStr.length() > 14 || formatType == DB_STORE_DATE) {
            return toVisualString(dateStr);
        } else {
            char[] charArr = null;
            switch (formatType) {
            case HYPHEN_DISPLAY_DATE:
                charArr = new char[] { '-', '-', ' ', ':', ':' };
                break;
            case DOT_DISPLAY_DATE:
                charArr = new char[] { '.', '.', ' ', ':', ':' };
                break;
            case CN_DISPLAY_DATE:
                charArr = new char[] { '年', '月', ' ', ':', ':' };
                break;
            default:
                charArr = new char[] { '-', '-', ' ', ':', ':' };
            }
            try {
                SimpleDateFormat sdf1 = null;
                SimpleDateFormat sdf2 = null;
                switch (dateStr.length()) {
                case 6:
                    sdf1 = new SimpleDateFormat("yyyyMM");
                    sdf2 = new SimpleDateFormat("yyyy'" + charArr[0] + "'MM");
                    break;
                case 8:
                    sdf1 = new SimpleDateFormat("yyyyMMdd");
                    sdf2 = new SimpleDateFormat("yyyy'" + charArr[0] + "'MM'" + charArr[1] + "'dd");
                    break;
                case 10:
                    sdf1 = new SimpleDateFormat("yyyyMMddHH");
                    sdf2 = new SimpleDateFormat("yyyy'" + charArr[0] + "'MM'" + charArr[1] + "'dd'"
                            + "+charArr[2]" + "'HH");
                    break;
                case 12:
                    sdf1 = new SimpleDateFormat("yyyyMMddHHmm");
                    sdf2 = new SimpleDateFormat("yyyy'" + charArr[0] + "'MM'" + charArr[1] + "'dd'" + charArr[2]
                            + "'HH'" + charArr[3] + "'mm");
                    break;
                case 14:
                    sdf1 = new SimpleDateFormat("yyyyMMddHHmmss");
                    sdf2 = new SimpleDateFormat("yyyy'" + charArr[0] + "'MM'" + charArr[1] + "'dd'" + charArr[2]
                            + "'HH'" + charArr[3] + "'mm'" + charArr[4] + "'ss");
                    break;
                default:
                    return dateStr;
                }
                return sdf2.format(sdf1.parse(dateStr));
            } catch (ParseException ex) {
                return dateStr;
            }
        }
    }

    /**
     * 将显示格式的时间字符串转换为数据库存储的类型
     * 
     * @param dateStr
     *            最小4位，最大19位。显示的时间格式时间串如:2004-12-12
     * @return 数据库存储的时间字符串
     */
    public static String toStoreStr(String dateStr) {
        if (dateStr == null || dateStr.trim().equals("")) {
            return "";
        }
        StringBuffer strBuf = new StringBuffer();
        for (int i = 0; i < dateStr.length(); i++) {
            if (dateStr.charAt(i) >= '0' && dateStr.charAt(i) <= '9') {
                strBuf.append(dateStr.charAt(i));
            }
        }
        return strBuf.toString();
    }

    /**
     * 将生日存储的时间格式转化为年龄（周岁，小数点后不计）
     * 
     * @param birthdayStr
     *            生日字段 "yyyymmdd"
     * @return 年龄
     */
    public static String birthdayToAge(String birthdayStr) {
        if (birthdayStr == null || birthdayStr.length() < 6) {
            return "";
        } else {
            int birthYear = Integer.parseInt(birthdayStr.substring(0, 4));
            int birthMonth = Integer.parseInt(birthdayStr.substring(4, 6));
            Calendar cal = new GregorianCalendar();
            int currYear = cal.get(Calendar.YEAR);
            int currMonth = cal.get(Calendar.MONTH);
            int age = currYear - birthYear;
            age -= (currMonth < birthMonth) ? 1 : 0;
            return "" + age;
        }
    }

    /**
     * 
     * @param dateTimeStr
     *            String 格式化的时间串
     * @param formatType
     *            数据格式类型 {@link #DB_STORE_DATE},{@link #EN_HTML_DISPLAY_DATE},{@link #CN_HTML_DISPLAY_DATE}
     * @param detal
     *            int 增加或减少的时间
     * @param field
     *            int 参见Calendar中关于时间字段属性的定义
     * @return String 返回的
     */
    public static String add(String dateTimeStr, int formatType, int detal, int field) {
        if (dateTimeStr == null || dateTimeStr.length() < 6) {
            return dateTimeStr;
        } else {
            try {
                String formatStr = null;
                switch (formatType) {
                case DB_STORE_DATE:
                    formatStr = "yyyyMMddHHmmss";
                    break;
                case HYPHEN_DISPLAY_DATE:
                    formatStr = "yyyy-MM-dd HH:mm:ss";
                    break;
                case DOT_DISPLAY_DATE:
                    formatStr = "yyyy.MM.dd HH:mm:ss";
                    break;
                case CN_DISPLAY_DATE:
                    formatStr = "yyyy'年'MM'月' HH：mm：ss";
                    break;
                default:
                    formatStr = "yyyyMMddHHmmss";
                    break;
                }

                formatStr = formatStr.substring(0, dateTimeStr.length());
                SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
                Date d = sdf.parse(dateTimeStr);
                GregorianCalendar g = new GregorianCalendar();
                g.setTime(d);
                g.add(field, detal);
                d = g.getTime();
                return sdf.format(d);
            } catch (ParseException ex) {
                ex.printStackTrace();
                return dateTimeStr;
            }
        }
    }

    // /**
    // * @param date Date 时间
    // * @param detal int 增加的时间
    // * @param field int 参见Calendar中关于时间字段属性的定义
    // * @return Date
    // */
    // public static Date add(Date date, int detal, int field)
    // {
    // Calendar g = new GregorianCalendar();
    // g.setTime(date);
    // g.add(field, detal);
    // return g.getTime();
    // }
    /**
     * 日期、时间格式化
     * 
     * @param date
     *            Date 将要被格式化的日期对象
     * @param outFmt
     *            String 返回样式，参照类说明，如：yyyy年MM月dd日
     * @return String 格式化后的日期、时间字符串，data为null时返回null，outFmt非法时返回yyyyMMdd格式
     */
    public static String getDateFormat(Date date, String outFmt) {
        if (null == date) {
            return null;
        }
        String newOutFmt = outFmt;

        if (null == newOutFmt || "".equals(newOutFmt.trim())) { // outFmt非法
            newOutFmt = "yyyyMMdd";
        }

        String retu = null;
        SimpleDateFormat dateFormat = null;
        try {
            dateFormat = new SimpleDateFormat(newOutFmt);
        } catch (IllegalArgumentException iaex) { // outFmt非法
            dateFormat = new SimpleDateFormat("yyyyMMdd");
        }
        retu = dateFormat.format(date);

        dateFormat = null;

        return retu;
    }

    /**
     * 把日期时间对象格式化为yyyyMMdd样式
     * 
     * @param date
     *            Date 将要被格式化的日期对象
     * @return String 格式化后的日期、时间字符串，如：20041001
     */
    public static String getDateFormat(Date date) {
        return getDateFormat(date, "yyyyMMdd");
    }
    
    /**
     * 把日期时间对象格式化为yyyyMMdd样式
     * 
     * @param date
     *            Date 将要被格式化的日期对象
     * @return String 格式化后的日期、时间字符串，如：20041001
     */
    public static String getDateFormatByFmt(Date date,String outFmt) {
        return getDateFormat(date, outFmt);
    }
    
    /**
     * 把系统当前日期时间格式化为指定的样式
     * 
     * @param outFmt
     *            String 返回样式，参照类说明，如：yyyy年MM月dd日
     * @return String 格式化后的日期、时间字符串，如：2004年10月01日
     */
    public static String getDateFormat(String outFmt) {
        return getDateFormat(new Date(), outFmt);
    }

    /**
     * 把系统当前日期时间格式化为默认样式yyyyMMdd
     * 
     * @return String 格式化后的日期、时间字符串，如：20041001
     */
    public static String getDateFormat() {
        return getDateFormat(new Date(), "yyyyMMdd");
    }

    /**
     * 日期、时间格式化
     * 
     * @param millis
     *            long the number of milliseconds（毫秒） since January 1, 1970,
     *            00:00:00 GMT.
     * @param outFmt
     *            String 返回样式，参照类说明，如：yyyy年MM月dd日
     * @return String 格式化后的日期、时间字符串
     */
    public static String getDateFormat(long millis, String outFmt) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(millis);

        String retu = getDateFormat(calendar.getTime(), outFmt);
        calendar = null;
        return retu;
    }

    /**
     * 日期、时间格式化
     * 
     * @param datestr
     *            String 存在一定格式的日期、时间字符串，如：20041001、200410011503
     * @param inFmt
     *            String 对datestr参数格式说明，参照类说明，如：yyyyMMdd、yyyyMMddHHmm
     * @param outFmt
     *            String 返回样式，参照类说明，如：yyyy年MM月dd日
     * @throws ParseException
     *             当datestr不能格式化为inFmt格式时抛出此异常
     * @return String 格式化后的日期、时间字符串，如：2004年10月01日、2004年10月01日 <BR>
     *         输出样式outFmt非法时，使用yyyyMMdd格式输出
     */
    public static String getDateFormat(String datestr, String inFmt, String outFmt) throws ParseException {
        if (null == datestr || "".equals(datestr.trim())) {
            return datestr;
        }

        if (null == inFmt || "".equals(inFmt.trim())) {
            return datestr;
        }

        String newOutFmt = outFmt;
        if (null == newOutFmt || "".equals(newOutFmt.trim())) { // 输出样式非法
            newOutFmt = "yyyyMMdd";
        }

        java.util.Date inDate = getDate(datestr, inFmt);

        if (null == inDate) { // 根据inFmt分析datestr时抛出异常
            return datestr;
        }

        String retu = getDateFormat(inDate, newOutFmt);
        inDate = null;
        return retu;
    }

    /**
     * 把日期时间字符串，按inFmt样式转化为日期对象，然后格式化为默认样式yyyyMMdd
     * 
     * @param datestr
     *            String 存在一定格式的日期、时间字符串，如：20041001、200410011503
     * @param inFmt
     *            String 对datestr参数格式说明，参照类说明，如：yyyyMMdd、yyyyMMddHHmm
     * @throws ParseException
     *             当datestr不能格式化为inFmt格式时抛出此异常
     * @return String 格式化后的日期、时间字符串，如：20041001、20041001
     */
    public static String getDateFormat(String datestr, String inFmt) throws ParseException {
        return getDateFormat(datestr, inFmt, "yyyyMMdd");
    }

    /**
     * 根据inFmt的样式，日期时间字符串转化为日期时间对象
     * 
     * @param datestr
     *            String 日期时间字符串，如：20041001、2004年10月01日 15:03
     * @param inFmt
     *            String 对datestr参数格式说明，参照类说明，如yyyyMMdd、yyyy年MM月dd日 HH:mm
     * @throws ParseException
     *             当datestr不能格式化为inFmt格式时抛出此异常
     * @return Date 日期时间对象，格式inFmt非法时，使用yyyyMMdd格式
     */
    public static Date getDate(String datestr, String inFmt) {
        if (null == datestr || "".equals(datestr.trim())) {
            return null;
        }

        String newInFmt = inFmt;
        if (null == newInFmt || "".equals(newInFmt.trim())) { // inFmt非法
            newInFmt = "yyyyMMdd";
        }
        
        if(inFmt.contains("-")){
        	  datestr=datestr.replaceAll("年", "-").replaceAll("月", "-");
        }else if(inFmt.contains("年")){
        	 datestr=datestr.replace("-", "年").replace("-", "月");
        }
          

        java.util.Date inDate = null;

        // 依据inFmt格式把日期字符串转化为日期对象
        SimpleDateFormat inDateFormat = new SimpleDateFormat(newInFmt);
        inDateFormat.setLenient(true);
        try {
			inDate = inDateFormat.parse(datestr);
		} catch (ParseException e) {
			Assert.fail("时间转换失败");
		}

        inDateFormat = null;
        return inDate;
    }
    
    /**
     * 
     * @param date1
     * @param date2
     * @return
     * @author:  
     */
    public static int dateDiff(Date date1,Date date2){
    	if(date1.compareTo(date2) == 0){
    		return 0;
    	}//Math.abs
    	long second = ((date1.getTime() - date2.getTime())) / 1000;
    	return (int) (second / SECONDS_ONE_DAY);
    }
    
    
    /**
     * 比较两个日期的时间差，如果
     * @param dateStr1
     * @param dateStr2
     * @param inFmt
     * @return
     * @author:  
     */
    public static int dateDiff(String dateStr1,String dateStr2,String inFmt){
    	Date date1 = null;
    	Date date2 = null;
		try {
			date1 = getDate(dateStr1, inFmt);
			date2 = getDate(dateStr2, inFmt);
		} catch (Exception e) {
			return -1;
		}
    	
    	return dateDiff(date1, date2);
    }

    /**
     * 对日期时间对象进行调整，实现如昨天是几号，去年的今天星期几等. <BR>
     * 例子：
     * 
     * <pre>
     * &lt;blockquote&gt;
     * 计算去年今天星期几
     * Date date = DateUtils.addDate(new Date(),Calendar.YEAR,-1);
     * System.out.println(DateUtils.getDateFormat(date,&quot;E&quot;));
     * 打印60天后是什么日期，并显示为 yyyy-MM-dd 星期
     * Date date = DateUtils.addDate(new Date(),Calendar.DATE,60);
     * System.out.println(DateUtils.getDateFormat(date,&quot;yyyy-MM-dd E&quot;));
     * &lt;/blockquote&gt;
     * </pre>
     * 
     * @param date
     *            Date 需要调整的日期时间对象
     * @param calendarField
     *            int 对日期时间对象以什么单位进行调整：
     * 
     * <pre>
     * &lt;blockquote&gt;
     * 年 Calendar.YEAR
     * 月 Calendar.MONTH
     * 日 Calendar.DATE
     * 时 Calendar.HOUR
     * 分 Calendar.MINUTE
     * 秒 Calendar.SECOND
     * &lt;/blockquote&gt;
     * </pre>
     * 
     * @param amount
     *            int 调整数量，>0表向后调整（明天，明年），<0表向前调整（昨天，去年）
     * @return Date 调整后的日期时间对象
     */
    public static Date addDate(Date date, int calendarField, int amount) {
        if (null == date) {
            return date;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(calendarField, amount);
        return calendar.getTime();
    }

    /**
     * 对日期时间对象进行调整.
     * 
     * @param datestr
     *            String 需要调整的日期时间字符串，它的格式为yyyyMMdd
     * @param calendarField
     *            int 对日期时间对象以什么单位进行调整
     * @param amount
     *            int 调整数量
     * @throws ParseException
     *             当datestr不能格式化为yyyyMMdd格式时抛出此异常
     * @return Date 调整后的日期时间对象
     * @see #addDate(java.util.Date, int, int)
     */
    public static Date addDate(String datestr, int calendarField, int amount)  {
        return addDate(getDate(datestr, "yyyyMMdd"), calendarField, amount);
    }
    
	/**
	 * 数字字符串转化为整数
	 * 
	 * @param intStr
	 *            String 待转化的数字字符串
	 * @param intDef
	 *            int 当intStr为空或空字符串时返回的缺省值
	 * @return int 返回由数字字符串转化成的数字，当intStr为空或空字符串时，返回缺省值intDef
	 */
	private static int getInt(String intStr, int intDef) {
		if (null == intStr || "".equals(intStr.trim())) {
			return intDef;
		}

		int intRetu = intDef;

		Double db = new Double(intStr);
		intRetu = db.intValue();
		return intRetu;
	}
	
    /**
     * 根据出生日期，计算出在某一个日期的年龄
     * 
     * @param birthday
     *            Date 出生日期时间对象
     * @param date2
     *            Date 计算日期对象
     * @return int 返回date2那一天出生日期为birthday的年龄，如果birthday大于date2则返回-1
     */
    public static int getAge(Date birthday, Date date2) {
        if (null == birthday || null == date2) {
            return -1;
        }

        if (birthday.after(date2)) { // birthday大于date2
            return -1;
        }

        int ibdYear =  getInt(getDateFormat(birthday, "yyyy"), -1);
        int idate2Year =  getInt(getDateFormat(date2, "yyyy"), -1);

        if (ibdYear < 0 || idate2Year < 0) {
            return -1;
        }
        if (ibdYear > idate2Year) {
            return -1;
        }

        return idate2Year - ibdYear + 1;
    }

    /**
     * 根据出生日期，计算出当前的年龄
     * 
     * @param birthday
     *            Date 出生日期时间对象
     * @return int 返回出生日期为birthday的年龄，如果birthday大于当前系统日期则返回-1
     */
    public static int getAge(Date birthday) {
        return getAge(birthday, new Date());
    }

    /**
     * 根据出生日期，计算出当前的年龄
     * 
     * @param birthdaystr
     *            String 出生日期时间字符串，其格式一定为yyyyMMdd
     * @throws ParseException
     *             当datestr不能格式化为yyyyMMdd格式时抛出此异常
     * @return int 返回出生日期为birthday的年龄，如果birthday大于当前系统日期则返回-1
     */
    public static int getAge(String birthdaystr) throws ParseException {
        return getAge(getDate(birthdaystr, "yyyyMMdd"));
    }

    /**
     * 得到14位的当前格式化时间
     * 
     * @param formatType
     *            时间格式的类型{@link #DB_STORE_DATE},{@link
     *            #EN_HTML_DISPLAY_DATE},{@link #CN_HTML_DISPLAY_DATE}
     * @return java.lang.String
     */
    public static String getCurrTime(int formatType) {
        if (formatType < DB_STORE_DATE || formatType > CN_DISPLAY_DATE) {
            throw new IllegalArgumentException("时间格式化类型不是合法的值。");
        } else {
            String formatStr = null;
            switch (formatType) {
            case DB_STORE_DATE:
                formatStr = "yyyyMMddHHmmss";
                break;
            case HYPHEN_DISPLAY_DATE:
                formatStr = "yyyy'-'MM'-'dd HH:mm:ss";
                break;
            case DOT_DISPLAY_DATE:
                formatStr = "yyyy.MM.dd HH:mm:ss";
                break;
            case CN_DISPLAY_DATE:
                formatStr = "yyyy'年'MM'月'dd HH:mm:ss";
                break;
            default:
                formatStr = "yyyyMMddHHmmss";
                break;
            }
            SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
            return sdf.format(new Date());
        }
    }

    /**
     * 得到8位的当前格式化日期
     * 
     * @param formatType
     *            时间格式的类型{@link #DB_STORE_DATE},{@link
     *            #EN_HTML_DISPLAY_DATE},{@link #CN_HTML_DISPLAY_DATE}
     * @return java.lang.String
     */
    public static String getCurrDate(int formatType) {
        if (formatType < DB_STORE_DATE || formatType > CN_DISPLAY_DATE) {
            throw new IllegalArgumentException("时间格式化类型不是合法的值。");
        } else {
            String formatStr = null;
            switch (formatType) {
            case DB_STORE_DATE:
                formatStr = "yyyyMMdd";
                break;
            case HYPHEN_DISPLAY_DATE:
                formatStr = "yyyy-MM-dd";
                break;
            case DOT_DISPLAY_DATE:
                formatStr = "yyyy.MM.dd";
                break;
            case CN_DISPLAY_DATE:
                formatStr = "yyyy'年'MM'月'dd";
                break;
            default:
                formatStr = "yyyyMMdd";
                break;
            }
            SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
            return sdf.format(new Date());
        }
    }

    /**
     * 得到6位的当前格式化年月
     * 
     * @param formatType
     *            时间格式的类型{@link #DB_STORE_DATE},{@link
     *            #EN_HTML_DISPLAY_DATE},{@link #CN_HTML_DISPLAY_DATE}
     * @return java.lang.String
     */
    public static String getYearMonth(int formatType) {
        if (formatType < DB_STORE_DATE || formatType > CN_DISPLAY_DATE) {
            throw new IllegalArgumentException("时间格式化类型不是合法的值。");
        } else {
            String formatStr = null;
            switch (formatType) {
            case DB_STORE_DATE:
                formatStr = "yyyyMM";
                break;
            case HYPHEN_DISPLAY_DATE:
                formatStr = "yyyy-MM";
                break;
            case DOT_DISPLAY_DATE:
                formatStr = "yyyy.MM";
                break;
            case CN_DISPLAY_DATE:
                formatStr = "yyyy'年'MM'月'";
                break;
            default:
                formatStr = "yyyyMM";
                break;
            }
            SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
            return sdf.format(new Date());
        }
    }

    /**
     * 获取时间所对应的毫秒
     * 
     * @param datetime
     *            String 时间字符串
     * @param inFmt
     *            String 时间格式化串
     * @return long 毫秒数
     * @throws ParseException
     *             ParseException
     */
    public static long getTimeValue(String datetime, String inFmt) throws ParseException {
        return getDate(datetime, inFmt).getTime();
    }

    /**
     * 获取时间字符串
     * 
     * @param milliSeconds
     *            long 从1970年到现在的毫
     * @param formatType
     *            int 时间类型
     * @return String 时间字符串
     */
    public static String getTimeStr(long milliSeconds, int formatType) {
        Date d = new Date(milliSeconds);
        return getTimeStr(d, formatType);
    }

    /**
     * getTimeByValue
     * 
     * @param time
     *            时间
     * @param timeOldFormat
     *            旧时间格式
     * @param timeNewFormat
     *            新时间格式
     * @return String
     * @author:Administrator
     */
    public static String getTimeByValue(String time, String timeOldFormat, String timeNewFormat) {
		SimpleDateFormat oldSdf = new SimpleDateFormat(timeOldFormat);
        SimpleDateFormat newSdf = new SimpleDateFormat(timeNewFormat);
        String newTime = time;
        try {
            if (org.apache.commons.lang.StringUtils.isNotBlank(time)) {
                // Date times = oldSdf.parse(time);

                newTime = newSdf.format(newSdf.parse(time));
            }
        } catch (ParseException e1) {
            e1.printStackTrace();
        }
        return newTime;
    }
    
    /**
     * 返回上月的起始日期和结束日期，格式YYYYMMDD
     * @param time
     * @return
     * @author:
     */
    public static String[] getLastMonthBetweenDay(Date time){
    	Calendar cal = Calendar.getInstance();
        cal.setTime(time);
        int year = 0;
        int month = cal.get(Calendar.MONTH)-1; // 上个月月份
        if (month == 0) {
            year = cal.get(Calendar.YEAR) - 1;
            month = 12;
        } else {
            year = cal.get(Calendar.YEAR);
        }
        Calendar c = Calendar.getInstance();
        c.set(year, month, 1);
        int startDay = c.getActualMinimum(Calendar.DAY_OF_MONTH);//起始天数
        int endDay = c.getActualMaximum(Calendar.DAY_OF_MONTH); // 结束天数
        c.set(year, month,startDay);
        String startTime = getDateFormat(c.getTime());
        c.clear();
        c.set(year, month,endDay);
        String endTime = getDateFormat(c.getTime());
        return new String[]{startTime,endTime};
    }
    
    /**
     * 返回上月的起始日期和结束日期，格式YYYYMMDD
     * @param time
     * @return
     * @author:huanglm
     */
    public static String[] getLastMonthBetweenDayByFmt(Date time,String fmt){
    	Calendar cal = Calendar.getInstance();
        cal.setTime(time);
        int year = 0;
        int month = cal.get(Calendar.MONTH)-1; // 上个月月份
        if (month == 0) {
            year = cal.get(Calendar.YEAR) - 1;
            month = 12;
        } else {
            year = cal.get(Calendar.YEAR);
        }
        Calendar c = Calendar.getInstance();
        c.set(year, month, 1);
        int startDay = c.getActualMinimum(Calendar.DAY_OF_MONTH);//起始天数
        int endDay = c.getActualMaximum(Calendar.DAY_OF_MONTH); // 结束天数
        c.set(year, month,startDay);
        String startTime = getDateFormatByFmt(c.getTime(),fmt);
        c.clear();
        c.set(year, month,endDay);
        String endTime = getDateFormatByFmt(c.getTime(),fmt);
        return new String[]{startTime,endTime};
    }
    
    /**
     * 获取两时间字符串的时间间隔描述
     * 例如：2010-10-10 10:10:10与2010-10-20 20:20:20
     *    的时间间隔描述串为：10天10时10分10秒
     * 如果开始时间大于结束时间返回负数，如：-10时10分10秒 
     *    
     * @param beginTime 开始时间字符串
     * @param endTime 结束时间字符串
     * @param inFmt String 时间格式化串
     * @return 两时间字符串的时间差 如：12天03时25分08秒
     */
    public static String getTimeBetweenStr(String beginTime,String endTime,String inFmt){
    	SimpleDateFormat dfs = new SimpleDateFormat(inFmt);
		StringBuffer timeStrBuf = new StringBuffer();
		try {
			Date begin = dfs.parse(beginTime);
			Date end = dfs.parse(endTime);
			if (begin.compareTo(end) == 0 ) {
				return "1秒"; //如果开始时间等于结束时间 直接返回1秒
			}
			long between = (end.getTime() - begin.getTime()) / 1000; //除以1000是为了转换成秒
			if (between < 0 ) {
				timeStrBuf.append("-");
				between = -between;
			}
			long day = between / (24*60*60);
			long hour = between % (24*60*60) / 3600;
			long minute = between % (60*60) / 60;
			long second = between % 60;
			if (day != 0) {
				timeStrBuf.append(String.valueOf(day)+"天" );
			}
			if (hour != 0) {
				timeStrBuf.append(String.valueOf(hour)+"时" );
			}
			
			if(minute != 0 ) {
				timeStrBuf.append(String.valueOf(minute)+"分" );
			}
			if (second != 0 ) {
				timeStrBuf.append(String.valueOf(second)+"秒" );
			}
		} catch (Exception e) {
			return null;
		}
    	return timeStrBuf.toString();
    }
    
    /**
     * 给时间加上或减去指定毫秒，秒，分，时，天、月或年等，返回变动后的时间
     *
     * @param date 要加减前的时间，如果不传，则为当前日期
     * @param field  时间域，有Calendar.MILLISECOND,Calendar.SECOND,Calendar.MINUTE,<br>
     *        *  Calendar.HOUR,Calendar.DATE, Calendar.MONTH,Calendar.YEAR
     * @param amount 按指定时间域加减的时间数量，正数为加，负数为减。
     * @author huanglm
     * @return 变动后的时间
     */
    public static Date add(Date date, int field, int amount) {
        if (date == null) {
            date = new Date();
        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(field, amount);

        return cal.getTime();
    }

    /**
     * 
     * @param date
     * @param amount
     * @author huanglm
     * @return
     */
    public static Date addMilliSecond(Date date, int amount) {
        return add(date, Calendar.MILLISECOND, amount);
    }

    /**
     *
     * @param date 
     * @param amount 
     * @author huanglm
     * @return 
     */
    public static Date addSecond(Date date, int amount) {
        return add(date, Calendar.SECOND, amount);
    }

    /**
     * 
     * @param date
     * @param amount
     * @author huanglm
     * @return
     */
    public static Date addMiunte(Date date, int amount) {
        return add(date, Calendar.MINUTE, amount);
    }

    /**
     * 
     * @param date
     * @param amount
     * @author huanglm
     * @return
     */
    public static Date addHour(Date date, int amount) {
        return add(date, Calendar.HOUR, amount);
    }

    /**
     * 
     * @param date
     * @param amount
     * @author huanglm
     * @return
     */
    public static Date addDay(Date date, int amount) {
        return add(date, Calendar.DATE, amount);
    }

    /**
     * 
     * @param date
     * @param amount
     * @author huanglm
     * @return
     */
    public static Date addMonth(Date date, int amount) {
        return add(date, Calendar.MONTH, amount);
    }

    /**
     * 
     * @param date
     * @param amount
     * @author huanglm
     * @return
     */
    public static Date addYear(Date date, int amount) {
        return add(date, Calendar.YEAR, amount);
    }
	
}
